package com.easyaop.api.order;

import java.util.Iterator;
import java.util.SortedMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;

public class OrderList<T> implements Iterable<T> {
    protected final SortedMap<Long, T> objMap = new ConcurrentSkipListMap<>();

    //环绕数量也表示排序值的低位
    protected final AtomicInteger counter = new AtomicInteger(0);

    public long create(T obj) {
        int orderValue = getOrderValue(obj.getClass());
        long orderId;
        synchronized (counter) {
            int current = counter.get();
            long high = orderValue;
            high = high << 32;
            orderId = high | current;
            objMap.computeIfAbsent(orderId, key -> obj);
            counter.compareAndSet(current, current + 1);
        }
        return orderId;
    }

    public void create(long orderId, T obj) {
        objMap.computeIfAbsent(orderId, key -> obj);
    }

    private int getOrderValue(Class<?> target) {
        Order order = target.getAnnotation(Order.class);
        return order == null ? -1 : order.value();
    }

    /*private long getId(T around) {
        Order order = around.getClass().getAnnotation(Order.class);
        long high = order == null ? -1 : order.value();
        high = high << 32;
        int count = counter.getAndUpdate(current -> {
//            if (current >= Integer.MAX_VALUE) {
//                return 0; // 重置为0
//            }
            return current + 1; // 增加1
        });
        //order优先级使用高32位,计数器使用低32位
        long v = high + count;
        System.out.println("order:" + high + "count:" + count + "v:" + v);
        return v;
    }*/

    public void remove(long orderId) {
        objMap.remove(orderId);
    }

    public void removeIf(Predicate<T> predicate) {
        Iterator<Long> iterator = objMap.keySet().iterator();
        while (iterator.hasNext()) {
            Long key = iterator.next();
            T obj = objMap.get(key);
            if (predicate.test(obj)) {
                iterator.remove();
            }
        }
    }

    @Override
    public Iterator<T> iterator() {
        return objMap.values().iterator();
    }
}
